// Copyright (C) ZHENG Zhong <heavyzheng nospam-at gmail D0T com>
// http://www.zhengzhong.net/
//
// $Id: xslt_result.cpp 318 2009-03-02 14:03:21Z heavyzheng $
//

#ifndef ZZHENG_XML_SOURCE
#define ZZHENG_XML_SOURCE
#endif // ZZHENG_XML_SOURCE

#include <zzheng/xml/xslt/libxslt/xslt_result.hpp>

#include <libxslt/xsltutils.h>

#include <boost/shared_ptr.hpp>
#include <cassert>
#include <functional>
#include <string>


namespace zzheng {
namespace xml {
namespace xslt {
namespace libxslt_ {

    namespace {

        const char* to_chars(const xmlChar* chars) {
            return reinterpret_cast<const char*>(chars);
        }

        //! Function object for deleting an xsltStylesheet pointer. This function object is used
        //! as the deleter parameter of boost::shared_ptr<xsltStylesheet>.
        struct delete_xml_doc: public std::unary_function<xmlDoc*, void> {
            void operator()(xmlDoc* doc) const {
                if (doc != 0) {
                    xmlFreeDoc(doc);
                }
            }
        }; // struct delete_xml_doc

    } // anonymous namespace


    ////////////////////////////////////////////////////////////////////////////////////////////////

    xslt_result::xslt_result(): doc_(), stylesheet_() {
        // Do nothing.
    }

    xslt_result::xslt_result(xmlDoc* doc, const boost::shared_ptr<xsltStylesheet>& stylesheet)
    : doc_(), stylesheet_() {
        if (doc != 0) {
            doc_.reset(doc, delete_xml_doc());
            stylesheet_ = stylesheet;
        }
    }

    bool xslt_result::good() const {
        return (doc_ != 0 && stylesheet_ != 0);
    }

    std::string xslt_result::str() const {
        std::string str;
        if (doc_ != 0 && stylesheet_ != 0) {
            xmlChar* buffer = 0;
            int size = 0;
            int zero_is_ok = xsltSaveResultToString(&buffer, &size, doc_.get(), stylesheet_.get());
            if (zero_is_ok == 0) {
                str.assign(to_chars(buffer), to_chars(buffer + size));
            }
        }
        return str;
    }

    void xslt_result::save_to_file(const std::string& file_name) const {
        if (doc_ != 0 && stylesheet_ != 0) {
            xsltSaveResultToFilename(file_name.c_str(), doc_.get(), stylesheet_.get(), 0);
        }
    }


} // namespace zzheng::xml::xslt::libxslt_
} // namespace zzheng::xml::xslt
} // namespace zzheng::xml
} // namespace zzheng




